﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef PROPERTYCOMPONENTTYPEWIDGET_H
#define PROPERTYCOMPONENTTYPEWIDGET_H
#pragma once

#include "QtCommonWidget.h"

#include <QFrame>
#include <QString>
#include <stdint.h>
#include <vector>
#include <map>
#include <memory>


namespace PropertyWidget
{
    class CComponentTypeWidget;
    class CPropertyWidget;
    class QComboxGroups;
    class CComponentTypeEdit;

    /*!
    *@class CComponentTypeGroup
    *@brief 构件类型组
    *
    */
    class QT_COMMON_WIDGET_EXPORT CComponentTypeGroup
    {
    public:
        /*!
        *@brief      获取构件类型组的名称
        *@return const QString &
        */
        const QString &GroupName() const;
        /*!
        *@brief      获取构件类型组的图标
        *@return const QString &
        */
        const QString &GroupIconPath() const;
        /*!
        *@brief      获取构件类型组的唯一标识
        *@return int
        */
        int64_t UniqueID() const;
        /*!
        *@brief      构造函数
        *@param [in] QString const & groupName
        *@param [in] QString const & groupIconPath
        *@return 
        */
        CComponentTypeGroup(int64_t uniqueID, QString const &groupName, QString const &groupIconPath);
        /*!
        *@brief      析构函数
        *@return 
        */
        ~CComponentTypeGroup(){}
    private:
        QString m_groupName;
        QString m_groupIconPath;
        int64_t m_uniqueID;
    };

    /*!
    *@class CComponentTypeItem
    *@brief 构件类型项
    *
    */
    class QT_COMMON_WIDGET_EXPORT CComponentTypeItem
    {
    public:
        /*!
        *@brief      获取构件类型对应的组
        *@return CComponentTypeGroup *
        */
        CComponentTypeGroup *Owner() const;
        /*!
        *@brief      获取构件类型名称
        *@return const QString &
        */
        const QString &Name() const;
        /*!
        *@brief      获取构件类型图标名称
        *@return const QString &
        */
        const QString &IconFileName() const;
        /*!
        *@brief      获取构件类型的唯一标识
        *@return int
        */
        int64_t UniqueID() const;
        /*!
        *@brief      构造函数
        *@param [in] CComponentTypeGroup * owner
        *@param [in] QString const & name
        *@param [in] QString const & iconFileName
        *@return 
        */
        CComponentTypeItem(CComponentTypeGroup *owner, int64_t uniqueID, QString const &name, QString const &iconFileName);
        /*!
        *@brief      析构函数
        *@return 
        */
        ~CComponentTypeItem(){}

    private:
        CComponentTypeGroup * m_pOwner;
        QString m_name;
        QString m_iconFileName;
        int64_t m_uniqueID;
    };

    /*!
    *@class CComponentTypeWidget
    *@brief 构件类型子窗口
    *
    */
    class QT_COMMON_WIDGET_EXPORT CComponentTypeWidget : public QFrame
    {
        Q_OBJECT
    public:
        /*!
        *@brief                                                 构造函数
        */
        CComponentTypeWidget(QWidget *pParent = nullptr);
        /*!
        *@brief                                                 析构函数
        */
        virtual ~CComponentTypeWidget();

        /*!
        *@brief                                                 添加一个构件类型分组
        *@param [in] int groupIndex                             将构件类型分组添加到什么位置（位置必须是有效位置，否则无法添加）
        *@param [in] int uniqueID                               构件类型组的唯一标识
        *@param [in] QString const & groupName                  待添加的构件类型分组名称
        *@param [in] QString const & groupIconPath              待添加的构件类型分组图标路径
        *@return     CComponentTypeGroup *    添加成功则返回一个构件类型组
        */
        CComponentTypeGroup *AddComponentTypeGroup(int groupIndex, int64_t uniqueID, const QString &groupName, const QString &groupIconPath);
        /*!
        *@brief                                                 通过uniqueID来获取构件类型组
        *@param [in] const int uniqueID
        *@return CComponentTypeGroup *
        */
        CComponentTypeGroup *GetComponentTypeGroupByUniqueID(int64_t uniqueID) const;
        /*!
        *@brief                                                 根据分组索引获取构件类型分组
        *@param [in] int groupIndex                             构件类型组位置索引（位置必须是有效位置，否则无法计算正确）
        *@return     CComponentTypeGroup *                      返回所有的构件类型分组
        */
        CComponentTypeGroup *GetComponentTypeGroupByIndex(int groupIndex) const;
        /*!
        *@brief                                                 获取构件类型分组数
        *@return     int                                        分组数
        */
        int ComponentTypeGroupsCount() const;
        ///*!
        //*@brief                                                 获取所有的构件类型分组
        //*@return  QVector<CComponentTypeGroup *>                返回所有的构件类型分组
        //*/
        //const std::vector<CComponentTypeGroup *>& GetAllComponentTypeGroups() const;
        /*!
        *@brief                                                 移除构件类型组
        *@param [in] int groupIndex                             构件类型组位置索引
        *@return     bool                                       成功移除返回true
        */
        bool RemoveComponentTypeGroup(int groupIndex);
        /*!
        *@brief                                                 移除所有的构件类型组
        *@return     bool                                       成功移除返回true
        */
        bool RemoveAllComponentTypeGroup();
        /*!
        *@brief                                                 在指定的构件类型组里面添加一个构件类型
        *@param [in] int groupIndex                             构件类型组位置索引（位置必须是有效位置，否则无法添加正确）
        *@param [in] int indexInGroup                           构件类型位置索引（在groupIndex构件类型组内部的索引,必须是有效索引，否则无法添加正确）
        *@param [in] int uniqueID                               构件类型的唯一标识
        *@param [in] const QString & name                       待添加的构件类型名称
        *@param [in] const QString & cmptTypeIconPath           待添加的构件类型图标路径
        *@return     CComponentTypeItem *                       添加成功则返回一个构件类型
        */
        CComponentTypeItem *AddComponentType(int groupIndex, int indexInGroup, int64_t uniqueID, const QString &name, const QString &cmptTypeIconPath);
        /*!
        *@brief                                                 获取构件项
        *@param [in] int groupIndex                             构件类型组位置索引（位置必须是有效位置，否则无法计算正确）
        *@param [in] int indexInGroup                           构件类型位置索引（在groupIndex构件类型组内部的索引,必须是有效索引，否则无法计算正确）
        *@return     CComponentTypeItem *                       成功则返回构件类型项
        */
        CComponentTypeItem* GetComponentTypeByIndex(int groupIndex, int indexInGroup); 
        /*!
        *@brief                                                 通过UniqueID获取构件项
        *@param [in] int uniqueID
        *@return CComponentTypeItem *
        */
        CComponentTypeItem *GetComponentTypeByUniqueID(int64_t uniqueID) ;
        /*!
        *@brief                                                 当移除完组内最后一个条目以后 就移除组分隔条
        *@param [in] int groupIndex                             构件类型组位置索引
        *@param [in] int indexInGroup                           构件类型位置索引（在groupIndex构件类型组内部的索引,必须是有效索引，否则无法删除正确）
        *@return     bool                                       移除成功则返回true
        */
        bool RemoveComponentType(int groupIndex, int indexInGroup);
        /*!
        *@brief                                                 设置当前项
        *@param [in] int groupIndex                             构件类型组位置索引
        *@param [in] int indexInGroup                           构件类型位置索引
        *@return     bool                                       成功设置返回true
        */
        bool setCurrentComponentType(int groupIndex,int indexInGroup);
        /*!
        *@brief                                                 获取当前项
        *@param [in] int &groupIndex                            构件类型组索引
        *@param [in] int &indexInGroup                          构件类型索引
        *@return void
        */
        void GetCurrentComponentType(int &groupIndex, int &indexInGroup);
        /*!
        *@brief                                                 设置添加构件类型按钮的图标
        *@param [in] const QString & iconFileName               图标资源路径
        *@return     void
        */
        void setComponentTypeAddButtonIcon(const QString &iconFileName);
        /*!
        *@brief                                                 设置编辑构件类型按钮的图标
        *@param [in] const QString & iconFileName               图标资源路径
        *@return     void
        */
        void setComponentTypeModifyButtonIcon(const QString &iconFileName);

        /*!
        *@brief                                                 设置添加构件类型按钮的状态
        *@param [in] bool isEnable                              按钮的enable状态
        *@return     void
        */
        void setEnableComponentTypeAddButton(bool isEnable);
        /*!
        *@brief                                                 设置编辑构件类型按钮的状态
        *@param [in] bool isEnable                              按钮的enable状态
        *@return     void
        */
        void setEnableComponentTypeModifyButton(bool isEnable);
        /*!
        *@brief                                                 设置切换构件类型下拉框的状态
        *@param [in] bool isEnable                              下拉框的enable状态
        *@return     void
        */
        void setEnableComponentTypeChangeComboxGroup(bool isEnable);

        /*!
        *@brief                                                 显示多值状态
        *@param [in] const QString & name                       多值状态名称
        *@param [in] const QString & typeIconPath               多值状态图标路径
        *@return     void
        */
        void DisplayMultiValState(const QString &name, const QString & typeIconPath);

    protected slots:
        void OnComponentTypeAddButtonClick();
        void OnComponentTypeModifyButtonClick();
        void OnSelectComponentType(const CComponentTypeItem *pComponentTypeItem);

    signals:
        void TypeAddButtonClick(); 
        void TypeModifyButtonClick(); 
        void ComponentTypeChanged(const CComponentTypeItem *pComponentTypeItem); 

    private:
        int  m_curGroupTypeIndex;
        int  m_curTypeIndex;
        std::unique_ptr<QComboxGroups>        m_upComboxGroups;
        std::unique_ptr<CComponentTypeEdit>   m_upComponentTypeEditFrame;
        std::vector<std::unique_ptr<CComponentTypeGroup>>    m_ComponentTypeGroups;
        std::map<CComponentTypeGroup*, std::vector<std::unique_ptr<CComponentTypeItem>>>  m_ComponentTypeItems;
    };

}
#endif//PROPERTYCOMPONENTTYPEWIDGET_H
